package com.lhkj.ct.framework.interceptors;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.ImmutableMap;
import com.lhkj.ct.base.constants.ConfigConstants;
import com.lhkj.ct.base.constants.Constants;
import com.lhkj.ct.base.enums.DeleteStatus;
import com.lhkj.ct.base.enums.IamsServiceEnum;
import com.lhkj.ct.base.enums.ReturnStatus;
import com.lhkj.ct.base.exception.BusinessException;
import com.lhkj.ct.base.exception.SystemException;
import com.lhkj.ct.base.model.ro.ActionResult;
import com.lhkj.ct.base.utils.ShiroUtil;
import com.lhkj.ct.base.utils.http.HttpUtils;
import com.lhkj.ct.framework.auth.ro.WxOAuth2UserInfo;
import com.lhkj.ct.framework.auth.service.AuthService;
import com.lhkj.ct.framework.shiro.token.AccessTokenAuthenticationToken;
import com.lhkj.ct.meta.admin.service.SysConfigService;
import com.lhkj.ct.meta.modules.auth.common.enums.IdentType;
import com.lhkj.ct.meta.modules.auth.common.enums.UserType;
import com.lhkj.ct.meta.modules.auth.entity.TblUserIdentity;
import com.lhkj.ct.meta.modules.auth.service.UserIdentityService;
import com.lhkj.ct.meta.modules.patient.mapper.PatientMapper;
import com.lhkj.ct.meta.modules.patient.model.entity.TblPatient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 绑定单位拦截器
 */
@Component
@SuppressWarnings("NullableProblems")
public class BindUnitInterceptor implements HandlerInterceptor {

    private final Logger log = LoggerFactory.getLogger(BindUnitInterceptor.class);

    @Resource
    private UserIdentityService userIdentityService;

    @Resource
    private PatientMapper patientMapper;

    @Resource
    private AuthService authService;

    @Resource
    private SysConfigService sysConfigService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("绑定单位拦截器: 登录状态 = {}", ShiroUtil.getSubject().isAuthenticated());
        String code = request.getParameter("code");
        String unitId = request.getParameter("unitId");
        if (ShiroUtil.getSubject().isAuthenticated()) {
            // 绑定单位，更新删除状态
            patientMapper.update(new LambdaUpdateWrapper<TblPatient>()
                    .set(TblPatient::getPatUnit, unitId)
                    .set(TblPatient::getDelFlag, DeleteStatus.NORMAL)
                    .eq(TblPatient::getId, ShiroUtil.getAuthUserInfo().getUserId())
            );
            return true;
        }
        log.debug("绑定单位拦截器：code = {},unitId = {}, 请求来源：{}", code, unitId, request.getRequestURI());
        if (StringUtils.isBlank(code) || StringUtils.isBlank(unitId)) {
            return false;
        }
        String appId = sysConfigService.selectConfigByKey(ConfigConstants.SYS_WECHAT_APPID);
        if (appId.isEmpty()) {
            throw new SystemException("系统未配置默认公众号参数，请先前往参数配置进行配置");
        }
        String jsonResult = HttpUtils.sendGet(IamsServiceEnum.USERINFO_URL.getUrl(), ImmutableMap.of("code", code, "mpId", appId));
        ActionResult<WxOAuth2UserInfo> actionResult = JSONObject.parseObject(jsonResult, new TypeReference<ActionResult<WxOAuth2UserInfo>>() {
        });
        if (!Objects.equals(actionResult.getCode(), ReturnStatus.SUCCESS.getCode())) {
            throw new BusinessException(actionResult.getCode(), actionResult.getMessage());
        }
        String openId = actionResult.getData().getOpenid();
        log.debug("微信公众号openId：{}", openId);
        TblUserIdentity identity = userIdentityService.getByIdentity(UserType.PLATFORM, IdentType.WXP, openId);
        if (null == identity || null == patientMapper.selectById(identity.getUserId())) {
            UriComponentsBuilder redirectBuilder = UriComponentsBuilder.fromUriString(Constants.SERVICE_BASE_URL).path("/wechat/#/create-card");
            redirectBuilder.queryParam("unitId", unitId);
            String url = redirectBuilder.build().toUriString();
            response.sendRedirect(url);
            return false;
        }
        // 绑定单位，更新删除状态
        patientMapper.update(new LambdaUpdateWrapper<TblPatient>()
                .set(TblPatient::getPatUnit, unitId)
                .set(TblPatient::getDelFlag, DeleteStatus.NORMAL)
                .eq(TblPatient::getId, identity.getUserId())
        );
        AccessTokenAuthenticationToken token = new AccessTokenAuthenticationToken(UserType.PLATFORM, openId, IdentType.WXP);
        authService.h5SessionId(token);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    }

}
